package com.tudouji.project.produce.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.tudouji.common.utils.IdUtils;
import com.tudouji.common.utils.SecurityUtils;
import com.tudouji.common.utils.StringUtils;
import com.tudouji.common.utils.sql.SqlUtil;
import com.tudouji.framework.config.ProduceConfig;
import com.tudouji.framework.web.domain.AjaxResult;
import com.tudouji.framework.web.page.PageDomain;
import com.tudouji.framework.web.page.TableSupport;
import com.tudouji.project.bill.domain.Whinform;
import com.tudouji.project.bill.domain.Whinformitem;
import com.tudouji.project.bill.domain.Whoutform;
import com.tudouji.project.bill.domain.Whoutformitem;
import com.tudouji.project.bill.service.impl.WhinformServiceImpl;
import com.tudouji.project.bill.service.impl.WhoutformServiceImpl;
import com.tudouji.project.bill.service.impl.WhoutformitemServiceImpl;
import com.tudouji.project.permission.domain.Salespermission;
import com.tudouji.project.permission.service.impl.SalespermissionServiceImpl;
import com.tudouji.project.produce.domain.*;
import com.tudouji.project.produce.mapper.MatretapplyitemMapper;
import com.tudouji.project.product.domain.Salesspecification;
import com.tudouji.project.product.service.impl.SalesspecificationServiceImpl;
import com.tudouji.project.store.domain.Storehouseroom;
import com.tudouji.project.store.service.impl.StorehouseroomServiceImpl;
import com.tudouji.project.system.domain.SysUser;
import com.tudouji.project.system.service.impl.BusinesscodeServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.ConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tudouji.project.produce.mapper.ProduceplanMapper;
import com.tudouji.project.produce.service.IProduceplanService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 生产计划Service业务层处理
 *
 * @author tudouji
 * @date 2022-06-01
 */
@Slf4j
@Service
public class ProduceplanServiceImpl implements IProduceplanService {
    @Autowired
    private ProduceplanMapper produceplanMapper;

    @Autowired
    private SalespermissionServiceImpl permissionService;
    @Autowired
    private BusinesscodeServiceImpl codeService;
    @Autowired
    private PickinglistServiceImpl pickinglistService;

    @Autowired
    private WhoutformServiceImpl whoutformService;

    @Autowired
    private StorehouseroomServiceImpl houseService;

    @Autowired
    private WhinformServiceImpl whinformService;

    @Autowired
    private WhinapplyServiceImpl whinapplyService;

    @Autowired
    private MaterialretapplyServiceImpl mapplyService;

    @Autowired
    private WhoutformitemServiceImpl whoutformitemService;

    @Autowired
    private ScrapapplyServiceImpl scrapService;

    @Autowired
    private SalesspecificationServiceImpl speService;

    @Autowired
    private MatretapplyitemMapper  matretapplyitemMapper;



    /**
     * 查询生产计划
     *
     * @param guid 生产计划ID
     * @return 生产计划
     */
    @Override
    public AjaxResult selectProduceplanById(String guid) {
        AjaxResult result=new AjaxResult();
        Produceplan pp = produceplanMapper.selectProduceplanById(guid);
        result.put("pp",pp);
        Pickinglist plDetail = new Pickinglist();
        plDetail.setProduceplanid(guid);
        plDetail.setNotInStats(new Integer[]{0});
        List<Pickinglist> plsCollect = pickinglistService.findCollect(plDetail);

        Pickinglist pll = new Pickinglist();
        pll.setProduceplanid(guid);
        pll.setGtStats(100);
        List<Pickinglist> plss = pickinglistService.findCollect(pll);
        if (plsCollect.size() > 0){
            plsCollect.get(0).setWeightsum(plss.get(0).getWeightsum());
        }
        //领料信息
        result.put("plsCollect",plsCollect);
//        Pickinglist pl = new Pickinglist();
//        pl.setProduceplanid(guid);
//        pl.setNotInStats(new Integer[]{0});
        List<Pickinglist> pls = pickinglistService.findPPDetail(plDetail);
        //领料详情
        if (pls.size() > 0){
            result.put("plssum",pls.size());
            result.put("pls",pls);
        }

        //入库申请单数据
        Whinapply whinapply = new Whinapply();
        whinapply.setProduceplanid(guid);
        whinapply.setStatus(100);
        List<Whinapply> ws = whinapplyService.selectWhinapplyList(whinapply);
        if (ws.size() > 0) {
            String[] whinapplyids = new String[ws.size()];
            for (int i = 0; i < ws.size(); i++) {
                whinapplyids[i] = ws.get(i).getGuid();
            }
            //查询重量,数量
            Whinform whinform = new Whinform();
            whinform.setOrderids(whinapplyids);
            whinform.setWhintype(4);
            Double hgweight = whinformService.getSumWeight(whinform);
            result.put("hgweight",hgweight);
        }
        Whinapply wa = new Whinapply();
        wa.setProduceplanid(guid);
        wa.setNotStats(new Integer[]{0});
        List<Whinapply> wss = whinapplyService.selectList(wa);
        if (wss.size() > 0) {
            result.put("hgsum",wss.size());
            result.put("whinforms",wss);
        }
        String[] plids = new String[pls.size()];
        for (int i = 0; i < pls.size(); i++) {
            plids[i] = pls.get(i).getGuid();
        }
        //报废单数据
        List<Scrapapply> scraps = new ArrayList<>();
        Double scrapweight = new Double(0);
        Scrapapply scrap = new Scrapapply();
        scrap.setPickids(plids);
        scrap.setNotStats(new Integer[]{0});
        if (plids.length > 0){
            scraps = scrapService.selectScrapapplyList(scrap);
            scrapweight = scrapService.getSumWeight(scrap);
        }
        //报废单数量，重量，详情
        result.put("scrapweight",scrapweight);
        if (scraps.size() > 0){
            result.put("scrapsum",scraps.size());
            result.put("scraps",scraps);
        }
        //退料单数量，重量，详情
        Materialretapply ma = new Materialretapply();
        ma.setProduceplanid(guid);
//        ma.setType(1);
        ma.setNotStats(new Integer[]{0});
        List<Materialretapply> mas = mapplyService.selectMaterialretapplyList(ma);
        result.put("materialsum",mas.size());
        if (mas.size() != 0){
            String[] maids = new String[mas.size()];
            boolean isHave = false;
            for (int i = 0; i < mas.size(); i++) {
                if (mas.get(i).getStatus() == 100){
                    isHave = true;
                    maids[i] = mas.get(i).getGuid();
                }
            }
            if (!isHave){
                result.put("materialweight",0);
            }else{
                Matretapplyitem mai = new Matretapplyitem();
                mai.setMatretapplyids(maids);
                mai = matretapplyitemMapper.getSumWeight(mai);
                result.put("materialweight",mai.getWeight());
            }
        }else{
            result.put("materialweight",0);
        }
        if (mas.size() > 0){
            result.put("materials",mas);
        }
        result.put("code",200);
        return result;
    }

    /**
     * 查询生产计划列表
     *
     * @param produceplan 生产计划
     * @return 生产计划
     */
    @Override
    public List<Produceplan> selectProduceplanList(Produceplan produceplan, String status, String functionType) {

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (produceplan == null) {
            produceplan = new Produceplan();
        }

        if (org.apache.commons.lang.StringUtils.isNotBlank(status)) {
            String[] sts = status.split(",");
            Integer[] stress = (Integer[]) ConvertUtils.convert(sts, Integer.class);
            produceplan.setStats(stress);
        }
        produceplan.setCreateBy(sysUser.getUserId());

        //查询是否有全局权限

        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        log.info("---permissions.size: {}",permissions.size());
        if (permissions.size() > 0) {
            startPage();
            log.info("---------select list-----");
            return produceplanMapper.selectPlanList(produceplan);
        } else {
            log.info("---------select list2-----");
            // 是否有组织(库房)权限
            List<Salespermission> permissionsOrg = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "7");
            //查询库房+部门权限(领料)
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "3");
            permissionsOrg.addAll(permissions);
            startPage();
            if (permissionsOrg.size() > 0) {
                log.info("---------select list4-----");
                String[] roomids = new String[permissionsOrg.size()];
                for (int i = 0; i < permissionsOrg.size(); i++) {
                    roomids[i] = permissionsOrg.get(i).getSrguid();
                }
                produceplan.setRoomids(roomids);
                return produceplanMapper.selectProduceplansByPer(produceplan);
            } else {
                log.info("---------select list4-----");
                //查询个人的
                return produceplanMapper.selectProduceplanByUser(produceplan);
            }
        }
    }

    @Override
    public List<Produceplan> selectProduceplanList(String functionType) {

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Produceplan produceplan=new Produceplan();
        produceplan.setStatus(3);
        //查询是否有全局权限
        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        if (permissions.size() > 0) {
            return produceplanMapper.selectProduceplanList(produceplan);
        } else {
            produceplan.setCreateBy(sysUser.getUserId());
            // 是否有组织(库房)权限
            List<Salespermission> permissionsOrg = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "7");
            //查询库房+部门权限(领料)
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "3");
            permissionsOrg.addAll(permissions);
            if (permissionsOrg.size() > 0) {
                String[] roomids = new String[permissionsOrg.size()];
                for (int i = 0; i < permissionsOrg.size(); i++) {
                    roomids[i] = permissionsOrg.get(i).getSrguid();
                }
                produceplan.setRoomids(roomids);
                return produceplanMapper.selectProduceplansByPer(produceplan);
            } else {
                //查询个人的
                return produceplanMapper.selectProduceplanByUser(produceplan);
            }
        }
    }

    protected void startPage() {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

    /**
     * 新增生产计划
     *
     * @param produceplan 生产计划
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult insertProduceplan(Produceplan produceplan) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        produceplan.setCode(codeService.getCode("17"));
        produceplan.setStatus(3);
        produceplan.setCreateBy(sysUser.getUserId());
        produceplan.setCreateName(sysUser.getNickName());
        produceplan.setOperatorid(sysUser.getGuid());
        if(StringUtils.isNotEmpty(produceplan.getGuid())){
             produceplanMapper.updateProduceplan(produceplan);
        }else{
            String guid= IdUtils.fastSimpleUUID();
            produceplan.setGuid(guid);
            produceplan.setCode(codeService.getCode("17"));
             produceplanMapper.insertProduceplan(produceplan);
        }
        return AjaxResult.success();
    }

    /**
     * 修改生产计划
     *
     * @param produceplan 生产计划
     * @return 结果
     */
    @Override
    public int updateProduceplan(Produceplan produceplan) {
        return produceplanMapper.updateProduceplan(produceplan);
    }

    /**
     * 批量删除生产计划
     *
     * @param guids 需要删除的生产计划ID
     * @return 结果
     */
    @Override
    public int deleteProduceplanByIds(String[] guids) {
        return produceplanMapper.deleteProduceplanByIds(guids);
    }

    /**
     * 删除生产计划信息
     *
     * @param guid 生产计划ID
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult deleteProduceplanById(String  guid) {
        // 没有领料单可以删除
        Pickinglist pl = new Pickinglist();
        pl.setProduceplanid(guid);
        pl.setNotInStats(new Integer[]{0});
        List<Pickinglist> pls = pickinglistService.selectPickinglistList(pl);
        if (pls.size() != 0) {
            return AjaxResult.error("已领料，不能删除！");
        }else{
            produceplanMapper.deleteProduceplanById(guid);
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional
    public AjaxResult enable(String guid) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Pickinglist pl = new Pickinglist();
        pl.setProduceplanid(guid);
        pl.setStatus(4);
        List<Pickinglist> list = pickinglistService.selectPickinglistList(pl);

        for (Pickinglist pick : list) {
            pick.setStatus(3);
            pick.setOperatorid(sysUser.getGuid());
            pickinglistService.updatePickinglist(pick);
        }
        ///更新计划状态
        Produceplan plan = new Produceplan();
        plan.setGuid(guid);
        plan.setStatus(3);
        plan.setOperatorid(sysUser.getGuid());
        produceplanMapper.updateProduceplan(plan);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult finish(String planid, String confirmFlag) {
        AjaxResult result=new AjaxResult();
        result.put("code",200);
//        //没有领料单的，不允许结束
        Pickinglist pick=new Pickinglist();
        pick.setProduceplanid(planid);
        List<Pickinglist>  picks=new ArrayList<Pickinglist>();
        if(StringUtils.isBlank(confirmFlag)){
            pick.setNotInStats(new Integer[]{0});
            picks=pickinglistService.selectPickinglistList(pick);
            if(picks.size()<1){
                //没有领料单的，不允许结束
                result.put("code",500);
                result.put("msg", "noPick");
            }else{
                for (Pickinglist pk : picks) {
                    result.put("pickCode", pk.getCode());
                    if (pk.getStatus() < 100) {
                        // 领料单未出库的，不允许结束
                        result.put("code",500);
                        result.put("msg", "hasNoWhoutPick");
                        return result;
                    }
                    if (pk.getStatus() == 100) {
                        //只检查主料领料单是否有 入库单 、入库单是否已入库
                        if(pk.getPicktype()==1){
                            Whinapply apply = new Whinapply();
                            apply.setPickinglistid(pk.getGuid());
                            apply.setNotStats(new Integer[] {0});
                            List<Whinapply> applys = whinapplyService.selectWhinapplyList(apply);
                            if (applys == null || applys.size() < 1) {
                                // 未做产品入库的，不允许结束
                                result.put("code",500);
                                result.put("msg", "hasNoWhinApply");
                                return result;
                            } else {
                                for (Whinapply wp : applys) {
                                    if (wp.getStatus() < 100) {
                                        // 产品入库单未入库的，不允许结束
                                        result.put("code",500);
                                        result.put("msg", "hasNoWhinPick");
                                        return result;
                                    }
                                }
                            }
                        }
                        // 退料单未完成入库的，不允许结束
//                        Materialretapply mapply = new Materialretapply();
//                        mapply.setLinkedid(pk.getGuid());
//                        Integer[] mstats = { 1 };
//                        mapply.setStats(mstats);
                        int mapplys = mapplyService.countUNFinishMaterialret(pk.getGuid());
                        if (mapplys>0) {
                            // 退料单未完成入库的，不允许结束
                            result.put("code",500);
                            result.put("msg", "hasNoMotPick");
                            return result;
                        }
                    }
                }
            }
        }
        //重量计算（计算已出库的领料单）
        Pickinglist pk=new Pickinglist();
        pk.setProduceplanid(planid);
        pk.setStats(new Integer[]{100});
        picks=pickinglistService.selectPickinglistList(pk);

        if(StringUtils.isBlank(confirmFlag)){
            result.put("confirmFlag", "confirmFlag");
            if(picks.size()>0){
                if(picks.get(0).getFlag()==1){
                    //获取出库重量
                    BigDecimal outWeight=BigDecimal.ZERO;
                    //入库重量
                    BigDecimal inWeight=BigDecimal.ZERO;
                    //报废重量
                    BigDecimal scrapWeight=BigDecimal.ZERO;
                    //退料重量
                    BigDecimal returnWeight=BigDecimal.ZERO;
                    for(Pickinglist pl:picks){
                        //删除的领料单 不做处理
//                        if(pl.getStatus()!=0){
                            Whoutform out= whoutformService.selectWhoutformByOrderId(pl.getGuid());
                            if (null == out){
                                result.put("code",500);
                                result.put("msg", "hasNoWhoutPick");
                                return result;
                            }
                            Whoutformitem item=new Whoutformitem();
                            item.setWhoutid(out.getGuid());
                            List<Whoutformitem> whoutformitems = whoutformitemService.selectWhoutformitemList(item);
                            for(Whoutformitem i:whoutformitems){
                                Storehouseroom house=houseService.selectStorehouseroomById(i.getShrguid());
                                //辅料不参与计算
                                if(house.getShrtype()!=4){
                                    outWeight=outWeight.add(whoutformService.calculateWeight(i.getSpguid(), i.getWeight(), null, 3).get("toT"));
                                }
                            }

                            Whinapply apply=new Whinapply();
                            apply.setStatus(100);
                            apply.setPickinglistid(pl.getGuid());
                            List<Whinapply> applys=whinapplyService.selectWhinapplyList(apply);
                            if(applys.size()>0){
                                String[] applyids=new String[applys.size()];
                                for(int i=0;i<applys.size();i++){
                                    applyids[i] = applys.get(i).getGuid();
                                }
                                Whinform in=new Whinform();
                                in.setOrderids(applyids);
                                in.setWhintype(4);
                                List<Whinform> ins=whinformService.selectWhinformDetail(in);
                                for(Whinform wi:ins){
                                    for(Whinformitem it:wi.getWhinformitemList()){
                                        Storehouseroom house=houseService.selectStorehouseroomById(it.getShrguid());
                                        //辅料不参与计算
                                        if(house.getShrtype()!=4){
                                            inWeight=inWeight.add(whoutformService.calculateWeight(it.getSpguid(), it.getWeight(), null, 3).get("toT"));
                                        }
                                    }
                                }
                            }

                            Scrapapply sa=new Scrapapply();
                            sa.setPickinglistid(pl.getGuid());
                            List<Scrapapply> sas=scrapService.selectScrapapplyList(sa);
                            if(sas.size()>0){
                                for(Scrapapply sc:sas){
                                    if(sc.getStatus()!=0){
                                        for(Scrapapplyitem si:sc.getItems()){
                                            Salesspecification spe=speService.selectSalesspecificationById(si.getSpecguid());
                                            //辅料不参与计算
                                            if(spe.getType()!=4){
                                                scrapWeight=scrapWeight.add(whoutformService.calculateWeight(si.getSpecguid(), si.getWeight(), null, 3).get("toT"));
                                            }
                                        }
                                    }
                                }
                            }

                            Materialretapply ma=new Materialretapply();
                            ma.setLinkedid(pl.getGuid());
                            List<Materialretapply> mas=mapplyService.selectMaterialretapplyList(ma);
                            if(mas.size()>0){
                                String[] masids=new String[mas.size()];
                                for(Materialretapply m:mas){
                                    for(int i=0;i<mas.size();i++){
                                        masids[i] = mas.get(i).getGuid();
                                    }
                                    Whinform in=new Whinform();
                                    in.setOrderids(masids);
                                    in.setWhintype(4);
                                    List<Whinform> ins=whinformService.selectWhinformDetail(in);
                                    for(Whinform wi:ins){
                                        for(Whinformitem it:wi.getItems()){
                                            Storehouseroom house=houseService.selectStorehouseroomById(it.getShrguid());
                                            if(house.getShrtype()!=4){//辅料不参与计算
                                                returnWeight=returnWeight.add(whoutformService.calculateWeight(it.getSpguid(), it.getWeight(), null, 3).get("toT"));
                                            }
                                        }
                                    }
                                }
                            }
//                        }
                    }

                    BigDecimal lossPoint=new BigDecimal(ProduceConfig.getLossPoint());
                    BigDecimal lossWeight=outWeight.multiply(lossPoint).divide(new BigDecimal(100), 4, BigDecimal.ROUND_HALF_UP);
                    //允许最大损耗量
                    result.put("lossWeight", lossWeight);
                    result.put("lossPoint", lossPoint);

                    if(outWeight.compareTo(BigDecimal.ZERO)==-1){
                        if((outWeight.subtract(inWeight).subtract(scrapWeight).subtract(returnWeight)).compareTo(lossWeight)!=-1){
                            result.put("msg", "success");
                        }else{
                            result.put("code",500);
                            result.put("msg", "outWeight");
                        }
                    }else{
                        if((outWeight.subtract(inWeight).subtract(scrapWeight).subtract(returnWeight)).compareTo(lossWeight)!=1){
                            result.put("msg", "success");
                        }else{
                            result.put("code",500);
                            result.put("msg", "outWeight");
                        }
                    }
                    System.out.println("------outWeight--------"+outWeight);
                    System.out.println("------inWeight--------"+inWeight);
                    System.out.println("------scrapWeight--------"+scrapWeight);
                    System.out.println("------returnWeight--------"+returnWeight);
                    System.out.println("------lossPoint--------"+lossPoint);
                    System.out.println("------lossWeight--------"+lossWeight);
                    System.out.println("------weight--------"+outWeight.subtract(inWeight).subtract(scrapWeight).subtract(returnWeight));

                }else{//代工厂生产不校验重量
                    result.put("msg", "success");
                }
            }
        }
        if(StringUtils.isNotBlank(confirmFlag)){
            //所有验证通过后  更新领料单状态,计划状态
            this.updatePlanAndPick(planid);
            result.put("msg", "success");//保存成功
        }
        return result;
    }

    /**
     * 更新领料单/计划状态
     *
     * @param planid
     */
    public void updatePlanAndPick(String planid) {
        Pickinglist pl = new Pickinglist();
        pl.setProduceplanid(planid);
        pl.setStatus(100);
        List<Pickinglist> list = pickinglistService.selectPickinglistList(pl);
        for (Pickinglist pick : list) {
            pick.setStatus(105);
            pickinglistService.updatePickinglist(pick);
        }
        ///更新计划状态
        Produceplan plan = new Produceplan();
        plan.setGuid(planid);
        plan.setStatus(4);
        plan.setPlanend(new Date());
        produceplanMapper.updateProduceplan(plan);
    }

}
